<template>
  <div class="manage-baseMap-panel" ref="el">
    <Transition name="popover">
      <Teleport to="body">
        <div
          v-if="show"
          class="baseMap-popover"
          :class="[state.placement]"
          :style="{
            top: state.top,
            right: state.right,
            bottom: state.bottom,
            left: state.left,
          }">
          <div class="baseMap-popover__header" ref="draggableHeader">
            <span class="title">底图</span>
            <span class="close-btn" @click="$emit('close')">+</span>
          </div>
          <div class="baseMap-popover__content">
            <ul class="baseMap">
              <li
                v-for="(baseMap, index) in baseMaps"
                :class="{
                  'baseMap-card': true,
                  active: currentBaseMap === baseMap.id,
                }"
                :key="index"
                @click="selectBaseMap(baseMap)">
                <div><img :src="baseMap.image" alt="" /></div>
                <div>{{ baseMap.name }}</div>
              </li>
            </ul>
          </div>
          <div class="baseMap-popover__footer"></div>
        </div>
      </Teleport>
    </Transition>
    <slot />
  </div>
</template>

<script setup>
import {
  ref,
  defineProps,
  reactive,
  watch,
  onMounted,
  nextTick,
  onUnmounted,
} from "vue";

const props = defineProps({
  show: {
    type: Boolean,
    required: true,
  },
  placement: {
    type: String,
    default: "top",
  },
  baseMaps: {
    type: Array,
    required: true,
  },
});

const $emit = defineEmits(["close", "pickBaseMap"]);

// t-设置面板初始位置
const state = reactive({
  placement: "popover-content-top",
  top: "",
  right: "",
  bottom: "",
  left: "",
});

const el = ref();
watch(
  () => props.show,
  value => {
    if (value) {
      const contentEl = el.value.lastElementChild;
      const panelHeight = 440,
        panelWidth = 380,
        gap = 25;
      const { offsetHeight, offsetWidth, offsetTop, offsetLeft } = contentEl;

      switch (props.placement) {
        case "top":
          state.placement = "popover-content-top";
          state.left = `${offsetLeft}px`;
          state.top = `${offsetTop - gap - panelHeight}px`;
          break;
        case "right":
          state.placement = "popover-content-right";
          state.top = `${offsetTop}px`;
          state.left = `${offsetWidth + offsetLeft + gap}px`;

          break;
        case "bottom":
          state.placement = "popover-content-bottom";
          state.left = `${offsetLeft}px`;
          state.top = `${offsetHeight + offsetTop + gap}px`;
          break;
        case "left":
          state.placement = "popover-content-left";
          state.top = `${offsetTop}px`;
          state.left = `${offsetLeft - gap - panelWidth}px`;
          break;
        default:
          break;
      }

      if (offsetTop + panelHeight > window.innerHeight) {
        state.top = "";
        state.bottom = `${gap}px`;
      }

      if (offsetLeft + offsetWidth + gap + panelWidth > window.innerWidth) {
        state.left = "";
        state.right = `${gap}px`;
      }

    } else {
      state.top = "";
      state.right = "";
      state.bottom = "";
      state.left = "";
    }
  }
);

// t-面板自由拖动
let isDragging = false;
let offsetX, offsetY;
const draggableHeader = ref();

watch(
  () => props.show,
  show => {
    if (show) {
      nextTick(() => {
        // 监听鼠标按下事件
        draggableHeader.value.addEventListener(
          "mousedown",
          handleDraggableMouseDown
        );

        // 监听鼠标移动事件
        window.addEventListener("mousemove", handleDraggableMouseMove);

        // 监听鼠标松开事件
        window.addEventListener("mouseup", handleDraggableMouseUp);
      });
    }
  }
);

onUnmounted(() => {
  // 移除鼠标按下事件
  draggableHeader.value &&
    draggableHeader.value.removeEventListener(
      "mousedown",
      handleDraggableMouseDown
    );

  // 移除鼠标移动事件
  window.removeEventListener("mousemove", handleDraggableMouseMove);

  // 移除鼠标松开事件
  window.removeEventListener("mouseup", handleDraggableMouseUp);
});

// 面板头部按下事件
function handleDraggableMouseDown(e) {
  isDragging = true;
  // 计算鼠标相对于面板左上角的偏移量
  offsetX = e.clientX - draggableHeader.value.parentNode.offsetLeft;
  offsetY = e.clientY - draggableHeader.value.parentNode.offsetTop;
}

// 鼠标移动事件
function handleDraggableMouseMove(e) {
  if (isDragging) {
    // 根据鼠标移动的偏移量更新面板的位置
    state.left = e.clientX - offsetX + "px";
    state.top = e.clientY - offsetY + "px";
    state.bottom = "0px";
    state.right = "0px";
  }
}

// 鼠标松开事件
function handleDraggableMouseUp() {
  isDragging = false;
}

// 当前选择的底图
const currentBaseMap = ref(props.baseMaps.find(baseMap => baseMap.default)?.id);

// 切换底图
function selectBaseMap(baseMap) {
  if (currentBaseMap.value === baseMap.id) return;
  $emit(
    "pickBaseMap",
    baseMap,
    props.baseMaps.find(item => item.id === currentBaseMap.value)
  );
  currentBaseMap.value = baseMap.id;
}
</script>

<style lang="less" scoped>
.manage-baseMap-panel {
  background: none;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 3;
}
.popover-enter-active,
.popover-leave-active {
  transition: all 0.5s ease;
  transform: translateY(0px);
  opacity: 1;
}
.popover-enter-from,
.popover-leave-to {
  transform: translateY(-60px);
  opacity: 0;
}
.baseMap-popover {
  box-shadow: 0 0 5px #b3b3b3;
  width: 380px;
  position: absolute;
  background-color: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.4) 0%,
    rgba(255, 255, 255, 0.05) 100%
  );
  backdrop-filter: blur(10px);
  border-radius: 4px;
  z-index: 999;
  user-select: none;
  &__header {
    width: 100%;
    height: 41px;

    background-color: #464c5a;
    padding: 0 5px 0 10px;
    border-radius: 4px 4px 0 0;

    color: #eaf2ff;
    font-size: 18px;
    line-height: 41px;
    cursor: move;
    box-sizing: border-box;

    .close-btn {
      float: right;
      font-size: 32px;
      color: #eaf2ff;
      cursor: pointer;
      transform: rotate(45deg);
    }
  }
  &__content {
    height: 360px;
    background-color: rgba(39, 44, 54, 0.9);
    padding: 14px;
    overflow: auto;
    box-sizing: border-box;

    scrollbar-width: thin;
    scrollbar-color: #888 #272c36;

    &::-webkit-scrollbar {
      width: 8px;
    }

    &::-webkit-scrollbar-track {
      background: #272c36;
    }

    &::-webkit-scrollbar-thumb {
      background-color: #888;
      border-radius: 4px;
    }

    &::-webkit-scrollbar-thumb:hover {
      background-color: #555;
    }
    .baseMap {
      height: calc(100% - 40px);
      display: grid;
      gap: 5px;
      grid-template-columns: repeat(4, 1fr);
      justify-content: center;
      color: #fff;
      text-align: center;
      &-card {
        cursor: pointer;
        &:hover {
          color: #337fe5;
        }
        &.active {
          color: #337fe5;
        }
        img {
          border: 1px solid #4db3ff78;
          width: 75px;
          height: 70px;
          padding: 1px;
        }
      }
    }
  }

  &__footer {
    width: 100%;
    height: 39px;
    background-color: rgba(39, 44, 54, 0.9);

    line-height: 39px;
  }
}
</style>
